<?php
/**************************************************************************
 *
 *   Copyright 2010 American Public Media Group
 *
 *   This file is part of AIR2.
 *
 *   AIR2 is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   AIR2 is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with AIR2.  If not, see <http://www.gnu.org/licenses/>.
 *
 *************************************************************************/

require_once 'Search_Proxy.php';

/**
 * Search Controller
 *
 * @author pkarman
 * @package default
 */
class Search_Controller extends AIR2_Controller {

    /**
     * Parse QUERY_STRING to allow for duplicate values on a single param name.
     *
     * @return array
     */
    private function _parse_query_string() {
        $params = array();
        $qstr = $this->input->server('QUERY_STRING');
        if (!isset($qstr) || !strlen($qstr)) {
            return $params;
        }
        $query  = explode('&', $this->input->server('QUERY_STRING'));
        if (!count($query)) {
            return $params;
        }

        foreach ( $query as $param ) {
            list($name, $value) = explode('=', $param);
            $params[urldecode($name)][] = urldecode($value);
        }

        // single values are not in an array
        foreach ( $params as $key=>$p ) {
            if (count($p) == 1) {
                $params[$key] = $p[0];
            }
        }

        return $params;

    }


    /**
     *
     */
    public function index() {

        /* this method is a proxy only. if the request was for html, redirect to default
           search (sources).
         */
        if ($this->response_view == 'html') {
            redirect($this->uri_for('search/sources', $_GET));
            exit;
        }

        $get_params = $this->_parse_query_string();
        //Carper::carp(var_export($get_params, true));

        // we do our own "view" here since we are just proxying for search server.

        $search_proxy = new Search_Proxy(array(
                'url'           =>  AIR2_SEARCH_URL,
                'cookie_name'   =>  AIR2_AUTH_TKT_NAME,
            )
        );

        //Carper::carp("created search_proxy");

        $response = $search_proxy->response();

        //Carper::carp(var_export( $response['response'], true));

        if ($response['response']['http_code'] != 200) {
            header('X-AIR2: server error', false, $response['response']['http_code']);
        }

        if ($this->input->get_post('gzip')) {
            //Carper::carp("marking response encoding as gzip");
            header("Content-Encoding: gzip");
        }

        // browsers seem to handle these differently.
        if (preg_match('/application\/json/', $this->input->server('HTTP_ACCEPT'))) {
            header("Content-Type: application/json; charset=utf-8");
        }
        else {
            header("Content-Type: text/javascript; charset=utf-8");
        }

        echo $response['json'];

    }


    /**
     *
     *
     * @return unknown
     */
    private function get_activity_names() {
        $q = AIR2_Query::create();
        $q->from('ActivityMaster');
        $result = $q->execute(array(), Doctrine_Core::HYDRATE_ON_DEMAND);
        $acts = array();
        foreach ($result as $actm) {
            $acts[$actm->actm_id] = htmlspecialchars($actm->actm_name);
        }
        return $acts;
    }


    /**
     *
     *
     * @return unknown
     */
    private function get_organization_names() {
        $q = AIR2_Query::create();
        $q->from('Organization');   // TODO security filter?
        $result = $q->execute(array(), Doctrine_Core::HYDRATE_ON_DEMAND);
        $orgs = array();
        foreach ($result as $org) {
            $orgs[$org->org_uuid] = htmlspecialchars($org->org_display_name);
        }
        return $orgs;
    }



    /**
     *
     *
     * @return unknown
     */
    private function get_project_names() {
        $q = AIR2_Query::create();
        $q->from('Project');   // TODO security filter?
        $result = $q->execute(array(), Doctrine_Core::HYDRATE_ON_DEMAND);
        $projects = array();
        foreach ($result as $prj) {
            $projects[$prj->prj_uuid] = htmlspecialchars($prj->prj_display_name);
        }
        return $projects;


    }


    /**
     *
     *
     * @return unknown
     */
    private function get_inquiry_names() {
        $q = AIR2_Query::create();
        $q->from('inquiry');   // TODO security filter?
        $result = $q->execute(array(), Doctrine_Core::HYDRATE_ON_DEMAND);
        $inqs = array();
        foreach ($result as $inq) {
            $inqs[$inq->inq_uuid] = htmlspecialchars($inq->inq_ext_title);
        }
        return $inqs;


    }


    /**
     *
     *
     * @param unknown $path
     * @param unknown $payload
     * @param unknown $title
     */
    private function _html_view($path, $payload, $title) {

        //Carper::carp( "response_format: " . $this->response_format );
        //Carper::carp( "response_view: " . $this->response_view );

        $payload['c'] = $this;
        $payload['org_names'] = $this->get_organization_names();
        $payload['act_names'] = $this->get_activity_names();
        $payload['prj_names'] = $this->get_project_names();
        //$payload['inq_names'] = $this->get_inquiry_names(); // TODO might need to fetch these as needed.
        $payload['use_gzip'] = preg_match('/gzip/', $_SERVER['HTTP_ACCEPT_ENCODING']);

        // params we want to propagate through to the search server
        // these (mostly) adhere to the Search::OpenSearch API
        $ok_params = array('q', 'F', 'o', 'p', 's', 'format', 'b', 'start', 'limit', 'h', 'c', 'f', 'r');
        $payload['params'] = array();
        $get_params = $this->_parse_query_string();
        foreach ($ok_params as $p) {
            $payload['params'][$p] = isset($get_params[$p]) ? $get_params[$p] : NULL;
        }

        $payload['q'] = $payload['params']['q'];

        // the $query is the 'q' param plus and 'F' params, joined with implicit AND
        //Carper::carp( var_export( $payload['params'], true ));
        $query = $payload['q'];
        if ($payload['params']['F'] !== NULL) {
            $query .= implode(' ', $payload['params']['F']);
        }

        $payload['query'] = $query;

        // catch any exceptions the View might throw
        $output = '';
        try {
            $output = $this->load->view($path, $payload, true);
        }


        catch (Exception $err) {
            // re-throw the exception if we are not in production
            if (!$this->is_production) {
                show_error($err);
            }
            else {
                show_error("There was a server error. Please try again later.");
            }
        }


        $js = array();
        $html = array(
            'body' => $output,
            'head' => array(
                'js' => $js,
                'title' => AIR2_SYSTEM_DISP_NAME." - Search Results: $title",
            ),
        );
        $this->response($html);

    }


    /**
     *
     */
    public function sources() {
        $payload = array(
            'search_idx'    => 'sources',
            'search_label'  => 'All Sources',
        );
        if ($this->response_view == 'html') {
            $this->_html_view('search/sources', $payload, 'All Sources');
        }
        // TODO support other formats?
    }


    /**
     *
     */
    public function activesources() {
        $payload = array(
            'search_idx'    => 'active-sources',
            'search_label'  => 'Active Sources',
        );
        if ($this->response_view == 'html') {
            $this->_html_view('search/sources', $payload, 'Active Sources');
        }
        // TODO support other formats?
    }


    /**
     *
     */
    public function inquiries() {
        $payload = array('search_idx' => 'inquiries');
        if ($this->response_view == 'html') {
            $this->_html_view('search/inquiries', $payload, 'Queries');
        }
        // TODO support other formats?
    }


    /**
     *
     */
    public function activities() {
        $payload = array('search_idx' => 'activities');
        if ($this->response_view == 'html') {
            $this->_html_view('search/activities', $payload, 'Activities');
        }
        // TODO support other formats?
    }


    /**
     *
     */
    public function projects() {
        $payload = array('search_idx' => 'projects');
        if ($this->response_view == 'html') {
            $this->_html_view('search/projects', $payload, 'Projects');
        }
        // TODO support other formats?
    }



    /**
     *
     */
    public function responses() {
        $payload = array('search_idx' => 'responses');
        if ($this->response_view == 'html') {
            $this->_html_view('search/responses', $payload, 'Submissions');
        }
        // TODO support other formats?
    }


    /**
     *
     */
    public function help() {
        $payload = array();
        if ($this->response_view == 'html') {
            $this->_html_view('search/help', $payload, 'Help');
        }
    }


}
